import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import fs from 'fs/promises';
import natural from 'natural';

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const app = express();
const port = process.env.PORT || 5000;

// 存储文档内容
const documents = [];

// 存储对话历史
const conversations = new Map();

app.use(cors());
app.use(bodyParser.json());

// 简单的中文分词函数
function segmentChinese(text) {
    // 1. 移除标点符号
    const cleanText = text.replace(/[.,，。！？、；：""''（）]/g, ' ');
    // 2. 按空格分词
    const words = cleanText.split(/\s+/);
    // 3. 对每个可能的词进行进一步分词（2-4个字符的滑动窗口）
    const segments = new Set();
    words.forEach(word => {
        if (word.length <= 4) {
            segments.add(word);
        } else {
            // 2-4字符的滑动窗口
            for (let len = 2; len <= 4; len++) {
                for (let i = 0; i <= word.length - len; i++) {
                    segments.add(word.slice(i, i + len));
                }
            }
        }
    });
    return Array.from(segments);
}

// 计算两段文本的相似度
function calculateSimilarity(text1, text2) {
    const segments1 = segmentChinese(text1);
    const segments2 = segmentChinese(text2);
    
    // 创建词频向量
    const wordSet = new Set([...segments1, ...segments2]);
    const vector1 = new Array(wordSet.size).fill(0);
    const vector2 = new Array(wordSet.size).fill(0);
    
    const wordArray = Array.from(wordSet);
    segments1.forEach(word => {
        const index = wordArray.indexOf(word);
        vector1[index]++;
    });
    
    segments2.forEach(word => {
        const index = wordArray.indexOf(word);
        vector2[index]++;
    });
    
    // 计算余弦相似度
    let dotProduct = 0;
    let norm1 = 0;
    let norm2 = 0;
    
    for (let i = 0; i < vector1.length; i++) {
        dotProduct += vector1[i] * vector2[i];
        norm1 += vector1[i] * vector1[i];
        norm2 += vector2[i] * vector2[i];
    }
    
    if (norm1 === 0 || norm2 === 0) return 0;
    
    return dotProduct / (Math.sqrt(norm1) * Math.sqrt(norm2));
}

// 加载知识库文件
async function loadKnowledgeBase() {
    try {
        const filesDir = join(dirname(__dirname), 'files');
        const files = await fs.readdir(filesDir);
        
        for (const file of files) {
            if (file.endsWith('.txt')) {
                const content = await fs.readFile(join(filesDir, file), 'utf-8');
                // 将长文档分割成段落
                const paragraphs = content.split(/\n\s*\n/).filter(p => p.trim());
                paragraphs.forEach(paragraph => {
                    if (paragraph.trim()) {
                        documents.push({
                            filename: file,
                            content: paragraph.trim()
                        });
                    }
                });
            }
        }
        console.log(`Loaded ${documents.length} paragraphs from documents`);
    } catch (error) {
        console.error('Error loading knowledge base:', error);
    }
}

// 查找最相关的文档片段
function findRelevantPassages(query, context = '', maxResults = 3) {
    const searchText = `${query} ${context}`.trim();
    const results = documents.map(doc => ({
        ...doc,
        score: calculateSimilarity(searchText, doc.content)
    }));
    
    // 按相关性排序
    results.sort((a, b) => b.score - a.score);
    
    // 过滤掉相关性太低的结果
    const threshold = 0.1; // 调整阈值以获得更好的结果
    return results.filter(r => r.score > threshold).slice(0, maxResults);
}

// 生成回复
function generateResponse(query, passages) {
    // 按相关性分数过滤段落
    const relevantPassages = passages.filter(p => p.score > 0.1);
    
    if (!relevantPassages.length) {
        return "抱歉，我在知识库中没有找到相关的信息。";
    }

    // 如果只有一个相关段落，直接返回
    if (relevantPassages.length === 1) {
        return `根据知识库内容：${relevantPassages[0].content}`;
    }

    // 综合多个段落的内容
    const combinedResponse = relevantPassages
        .map((passage, index) => `${index + 1}. ${passage.content}（相关度：${passage.score.toFixed(2)}）`)
        .join('\n\n');

    return `根据知识库内容，找到以下相关信息：\n\n${combinedResponse}`;
}

// API 路由
app.post('/api/chat', async (req, res) => {
    try {
        const { query, conversationId } = req.body;
        if (!query) {
            return res.status(400).json({ error: 'Query is required' });
        }

        // 获取或创建对话历史
        if (!conversations.has(conversationId)) {
            conversations.set(conversationId, []);
        }
        const history = conversations.get(conversationId);

        // 使用最近的对话历史作为上下文
        const recentContext = history.slice(-2).map(h => h.content).join(' ');
        
        // 查找相关段落
        const relevantPassages = findRelevantPassages(query, recentContext);
        
        // 生成回复
        const answer = generateResponse(query, relevantPassages);

        // 更新对话历史
        history.push({
            role: 'user',
            content: query,
            timestamp: Date.now()
        });
        history.push({
            role: 'assistant',
            content: answer,
            timestamp: Date.now()
        });

        // 只保留最近的10条对话
        if (history.length > 20) {
            history.splice(0, 2);
        }

        // 构建响应
        const response = {
            conversationId: conversationId || Date.now().toString(),
            answer,
            history: history,
            passages: relevantPassages.map(p => ({
                content: p.content,
                score: p.score
            }))
        };

        res.json(response);
    } catch (error) {
        console.error('Error processing query:', error);
        res.status(500).json({ error: 'Internal server error' });
    }
});

// 获取对话历史
app.get('/api/chat/:conversationId', (req, res) => {
    const { conversationId } = req.params;
    const history = conversations.get(conversationId) || [];
    res.json({ history });
});

// 清除对话历史
app.delete('/api/chat/:conversationId', (req, res) => {
    const { conversationId } = req.params;
    conversations.delete(conversationId);
    res.json({ message: 'Conversation history cleared' });
});

// 启动服务器
async function startServer() {
    await loadKnowledgeBase();
    app.listen(port, () => {
        console.log(`Server is running on port ${port}`);
    });
}

startServer();
